package com.gvsoft.communication.server.socket;

import com.gvsoft.communication.net.NSocket;
import com.gvsoft.communication.server.serverstatus.DefaultStatusHandle;
import com.gvsoft.communication.server.serverstatus.IStatusManageHandle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created with IntelliJ IDEA.
 * ProjectName:gvMsgRouting
 * Author: zhaoqiubo
 * Date: 15/8/13
 * Time: 上午10:07
 * Desc: NSocket管理工具类
 */
public class NSocketManager {

    private static Logger logger = LogManager.getLogger("server");
    /**
     * 存储以UserID(ClientID)为key,NSocket为value的map
     */
    private static Map<String, NSocket> userIDNSockets = new ConcurrentHashMap<>();
    /**
     * 存储以token为key,NSocket为value的map
     */
    private static Map<String, NSocket> tokenNSockets = new ConcurrentHashMap<>();

    private static Map<String, NSocket> unRegNSockets = new ConcurrentHashMap<>();
    private static IStatusManageHandle statusHandle = new DefaultStatusHandle();

    public static void addUnregNSocket(NSocket nSocket) {
        unRegNSockets.put(nSocket.getToken(), nSocket);
    }

    public static void removeUnregNSocket(String token) {
        unRegNSockets.remove(token);
    }

    public static Map<String, NSocket> getUnregNSockets() {
        return unRegNSockets;
    }

    public static NSocket getUnregNSoket(String token) {
        return unRegNSockets.get(token);
    }

    private static Lock lock = new ReentrantLock();

    public static int getUserMapSize() {
        return userIDNSockets.size();
    }

    public static int getTokenMapSize() {
        return tokenNSockets.size();
    }

    public static NSocket getConnByToken(String token) {

        if (tokenNSockets.get(token) != null) {
            return tokenNSockets.get(token);
        } else {
            return null;
        }

    }

    public static NSocket getConnByUserId(String userId) {

        return userIDNSockets.get(userId);

    }

    public static void addConn2Cache(NSocket conn) {
        statusHandle.beforeAdded(conn);

        NSocket nSocket = null;
        //当用户重复登录时，会形成新的token，为了保证两个map的一致性，需要删除原来的token；

        if (userIDNSockets.containsKey(conn.getUserId())) {

            nSocket = userIDNSockets.get(conn.getUserId());
            NSocket nSocketToken = tokenNSockets.get(nSocket.getToken());
            statusHandle.onReconnect(conn, nSocketToken);
            nSocketToken.close();
            logger.info("发生了重连，清理旧的token连接：token为：" + nSocket.getToken());

        }
        lock.lock();
        try {

            if (nSocket != null) {
                tokenNSockets.remove(nSocket.getToken());
            }
            tokenNSockets.put(conn.getToken(), conn);
            userIDNSockets.put(conn.getUserId(), conn);
        } finally {
            lock.unlock();
        }

        statusHandle.afterAdded(conn);
    }

    public static void regStatusHandle(IStatusManageHandle sth) {
        statusHandle = sth;
    }

    public static void removeNSocket(String token, String userId) {
        statusHandle.beforeRemoved(token, userId);
        lock.lock();
        try {
            tokenNSockets.remove(token);
            userIDNSockets.remove(userId);
        } finally {
            lock.unlock();
        }
        statusHandle.afterRemoved(token, userId);
    }

    public static Map<String, NSocket> getConnCache() {
        return tokenNSockets;
    }

    public static Map<String, NSocket> getNSocketMapById() {
        return userIDNSockets;
    }

}
